#ifndef  HELPER_OBJECT_STANDARDARRAY_H
#define  HELPER_OBJECT_STANDARDARRAY_H

#include <string>
#include <vector>

#include "helper/object/Array.h"
#include "helper/object/Iterator.h"

namespace helper {
namespace object {

class String;
class Pointer;
class Hash;
class StandardArray : public Array{
public:
    StandardArray();
    ~StandardArray() override;

    size_t size() const override;

    const Array::ValueType * get(const int index) const override;

    std::pair<bool, char> getByte(const int index) override;
    std::pair<bool, int> getInt(const int index) override;
    std::pair<bool, long long> getLongLong(const int index) override;
    std::pair<bool, double> getDouble(const int index) override;

    std::pair<bool, std::string> getStdString(const int index) override;

    String * getString(const int index) override;
    const String * getString(const int index) const override;
    Array * getArray(const int index) override;
    const Array * getArray(const int index) const override;
    Hash * getHash(const int index) override;
    const Hash * getHash(const int index) const override;

    std::pair<bool, void *> getPointer(const int index) override;
    int appendPointer(const void * ptr) override;

    int append(const Array::ValueType & o) override;

    int append(char ch) override;
    int append(int i) override;
    int append(long long ll) override;
    int append(double dbl) override;

    int append(const char * str) override;
    int append(const char * buffer, size_t len) override;
    int append(const char * buffer, size_t offset, size_t len) override;
    int append(size_t n, const char ch) override;
    int append(const std::string & str) override;


    Array::ValueType remove(const int index) override;
    Array::ValueType set(const int index, const ValueType & value) override;

    std::shared_ptr<Iterator<Array::ValueType>> iterator() const override;

    std::string toString() const override;
    Object * copy() const override;

    bool equals(const Object & obj) const override;

    void clear() override;

protected:
    friend class StandardArrayIterator;  
    void freeHolderResource(); 
private:
    std::vector<Array::ValueType> array;
};

class StandardArrayIterator : public Iterator<Array::ValueType> {
public:
    explicit StandardArrayIterator(Array & array);
    explicit StandardArrayIterator(const Array & array);
    ~StandardArrayIterator() override;

    bool hasNext() const override;
    const ElementType & next() override;

private:
    const Array & arrayRef;
    int index;
};

} // end of namespace object
} // end of namespace helper

#endif   /* HELPER_OBJECT_STANDARDARRAY_H */
